package com.cheboohui.iqs.taiping.direct.price;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cheboohui.iqs.common.basic.DoubleUtil;
import com.cheboohui.iqs.common.basic.StringUtil;
import com.cheboohui.iqs.common.basic.TimeUtil;
import com.cheboohui.iqs.spring.entity.Insurance;
import com.cheboohui.iqs.spring.entity.Policy;
import com.cheboohui.iqs.spring.entity.Price;
import com.cheboohui.iqs.spring.entity.price.request.PriceRequest;
import com.cheboohui.iqs.spring.entity.price.response.PriceResult;
import com.cheboohui.iqs.taiping.direct.ResTaiPing;
import com.cheboohui.iqs.taiping.direct.v.V02Request;

/**
 * 报价参数
 * 
 * @author xielonghai
 *
 */
public class PriceStep {
	/**
	 * logger:日志工具.
	 */
	private Log log = LogFactory.getLog(PriceStep.class);

	private String BZtime;// 交强险开始时间

	private String BStime;// 商业险开始时间

	private List<Insurance> insuranceList;// 保险信息

	private String session;// 太平接口回话session

	private final String orderNo;// 订单号

	private boolean tra = false;

	private boolean bus = false;

	private double person = 1.0;

	private double add = 1.0;

	private PriceRequest priceRequest;

	/**
	 * 构造器
	 * 
	 * @param priceRequest
	 * @param time
	 */
	public PriceStep(PriceRequest priceRequest, JSONObject obj) {
		this.priceRequest = priceRequest;
		this.insuranceList = priceRequest.getInsuranceList();
		this.session = obj.getString("session");
		this.orderNo = obj.getString("orderNo");
		this.request = new JSONObject();
		setDefault();
		setRequest();
	}

	/**
	 * 参数初始化
	 */
	private void setDefault() {
		int to = 1;
		for (Insurance i : insuranceList) {
			if (i.getCode().equals("TP")) {
				tra = true;
				BZtime = i.getBeginTime();
				to++;
			} else if (i.getCode().equals("BTR")) {
				bus = true;
				BStime = i.getBeginTime();
				to++;
			}

			if (to > 2)
				break;
		}

		if (StringUtil.isNulls(BStime))
			BStime = TimeUtil.timeNextDay("yyyy-MM-dd");
		else
			BStime = TimeUtil.timeToTime(BStime, TimeUtil.DEFAULT_TIME, TimeUtil.YMD);

		if (StringUtil.isNulls(BZtime))
			BZtime = TimeUtil.timeNextDay("yyyy-MM-dd");
		else
			BZtime = TimeUtil.timeToTime(BZtime, TimeUtil.DEFAULT_TIME, TimeUtil.YMD);
		log.info(orderNo + ",起保时间的初始变量设定结束....");
	}

	private JSONObject request;// 报价请求参数

	/**
	 * 报价流程
	 * 
	 * @return
	 */
	public PriceResult price() {
		log.info(orderNo + ",V02报价开始.........");
		ResTaiPing one = V02Request.requestV01(session, request);
		if (!one.isState())
			return new PriceResult(one.getError(), one.getMsg());

		log.info(orderNo + ",处理V02返回结果.........");
		Policy policy = new Policy();
		policy.setOrderNo(orderNo);

		if (tra) {
			JSONObject res = new JSONObject();

			res.put("priceTaxTotal",
					one.getResult().getJSONArray("itemKindBZ").getJSONObject(0).getDouble("priceTaxTotal"));
			res.put("kindCode", "TP");
			policy.setTraficNo(orderNo);
			policy.setTrafic(one.getResult().getJSONArray("itemKindBZ").getJSONObject(0).getDouble("priceTaxTotal"));
			policy.setTax(one.getResult().getJSONArray("tax").getJSONObject(0).getDouble("sumPayTax"));
			getRes(res, getStartDate(one.getResult(), "BZ"));
		}

		if (bus) {
			String businessBeginDate = getStartDate(one.getResult(), "BS");
			policy.setBusinessNo(orderNo);
			JSONArray arr = one.getResult().getJSONArray("itemKindBS");
			double price = 0.0;
			for (int i = 0; i < arr.size(); i++) {
				price += arr.getJSONObject(i).getDoubleValue("priceTaxTotal");
				getRes(arr.getJSONObject(i), businessBeginDate);
			}
			policy.setBusinessTotal(DoubleUtil.setDouble(price, 2));
		}
		policy.setTotal();
		policy.setCode("01");
		policy.setCodeValue("算费成功");
		return new PriceResult(new Price(policy, insuranceList));
	}

	private void getRes(JSONObject res, String time) {
		switch (res.getString("kindCode")) {
		case "01":// 机动车损失保险
			getRes("BL", res.getDouble("priceTaxTotal"), time);
			break;
		case "03":// 全车盗抢保险
			getRes("BT", res.getDouble("priceTaxTotal"), time);
			break;
		case "02":// 第三者责任保险
			getRes("BTR", "第三者责任保险", res.getDouble("priceTaxTotal"), time);
			break;
		case "041":// 车上人员责任保险（司机）
			getRes("BD", "车上人员责任保险（司机）", res.getDouble("priceTaxTotal"), time);
			break;
		case "044":// 车上人员责任保险（乘客）
			getRes("BP", "车上人员责任保险（乘客）", res.getDouble("priceTaxTotal"), time);
			break;
		case "11":// 玻璃单独破碎险
			getRes("BG", "玻璃单独破碎险", res.getDouble("priceTaxTotal"), time);
			break;
		case "13":// 自燃损失险
			getRes("BNP", res.getDouble("priceTaxTotal"), time);
			break;
		case "601":// 车损不计免
			getRes("BLD", "机动车损失保险不计免赔", res.getDouble("priceTaxTotal"), time);
			break;
		case "603":// 盗抢不计免
			getRes("BTD", "全车盗抢保险不计免赔", res.getDouble("priceTaxTotal"), time);
			break;
		case "602":// 商三不计免
			getRes("BTRD", "第三者责任保险不计免赔", res.getDouble("priceTaxTotal"), time);
			break;
		case "604":// 人员不计免
			getRes("PERSON", "人员不计免赔", res.getDouble("priceTaxTotal"), time);
			break;
		case "61":// 附加险不计免
			getRes("ADD", "附加险不计免赔", res.getDouble("priceTaxTotal"), time);
			break;
		case "21":// 车身划痕损失险
			getRes("BN", "车身划痕损失险", res.getDouble("priceTaxTotal"), time);

		case "TP":// 交强险
			getRes("TP", "交强险", res.getDouble("priceTaxTotal"), time);
		default:
			break;
		}
	}

	private void getRes(String code, Double price, String time) {
		Insurance i = getIns(code);
		if (null != i) {
			i.setBeginTime(time);
			i.setAmount(ComputeCar.compute(priceRequest.getCar().getPurchase(),
					priceRequest.getLicense().getRegisteredTime(), time));
			i.setEndTime(TimeUtil.timeNextYear(time, TimeUtil.DEFAULT_TIME));
			i.setPrice(price);
		}
	}

	private void getRes(String code, String value, Double price, String time) {
		if (code.equals("PERSON")) {
			Insurance i = getIns("BDD");
			if (null != i) {
				i.setBeginTime(time);
				i.setEndTime(TimeUtil.timeNextYear(time, TimeUtil.DEFAULT_TIME));
				i.setPrice(price / (person - 1.0));
			}
			Insurance ii = getIns("BPD");
			if (null != ii) {
				ii.setBeginTime(time);
				ii.setEndTime(TimeUtil.timeNextYear(time, TimeUtil.DEFAULT_TIME));
				ii.setPrice(price / (person - 1.0));
			}
		} else if (code.equals("ADD")) {
			Insurance i = getIns("BND");
			if (null != i) {
				i.setBeginTime(time);
				i.setEndTime(TimeUtil.timeNextYear(time, TimeUtil.DEFAULT_TIME));
				i.setPrice(price / (add - 1.0));
			}
			Insurance ii = getIns("BNPD");
			if (null != ii) {
				ii.setBeginTime(time);
				ii.setEndTime(TimeUtil.timeNextYear(time, TimeUtil.DEFAULT_TIME));
				ii.setPrice(price / (add - 1.0));
			}
		} else {
			Insurance i = getIns(code);
			if (null != i) {
				i.setBeginTime(time);
				i.setEndTime(TimeUtil.timeNextYear(time, TimeUtil.DEFAULT_TIME));
				i.setPrice(price);
			}
		}
	}

	private Insurance getIns(String code) {
		for (Insurance i : insuranceList) {
			if (i.getCode().equals(code))
				return i;
		}
		return null;
	}

	/** 获取保险开始时间 **/
	private String getStartDate(JSONObject price, String riskCode) {
		JSONArray arr = price.getJSONArray("risk");
		for (int i = 0; i < arr.size(); i++) {
			if (arr.getJSONObject(i).getString("riskCode").equals(riskCode))
				return arr.getJSONObject(i).getString("startDate");
		}
		return "false";
	}

	/**
	 * 报价请求参数设置
	 */
	private void setRequest() {
		request.put("orderNo", orderNo);
		// 交强险
		JSONObject BZ = new JSONObject();
		BZ.put("BZState", tra);
		if (tra) {
			BZ.put("BZtime", BZtime);
		}
		request.put("BZ", BZ);

		// 商业险
		JSONObject BS = new JSONObject();
		BS.put("BSState", bus);
		if (bus) {
			BS.put("BStime", BStime);
			JSONArray itemKindBS = new JSONArray();
			for (Insurance i : insuranceList) {
				JSONObject it = getIns(i);
				if (null != it && !it.isEmpty())
					itemKindBS.add(it);
			}
			request.put("itemKindBS", itemKindBS);
		}
		request.put("BS", BS);
		log.info(orderNo + ",初次报价请求参数设置结束....");
	}

	private JSONObject getBus(String code, Double insured, String ind, int type) {
		JSONObject it = new JSONObject();
		it.put("kindCode", code);// 险别代码
		it.put("insured", insured);// 保额--车上人员责任送入的为每人保额，其他险别送入的为总保额;除了车损险和盗抢险，其他险别该字段属于必传
		it.put("relatedInd", relatedInd(ind));// 是否投保不计免赔--1：是；0：否
		if (1 == type) {
			if ("1".equals(it.getString("relatedInd")))
				person = person + 1.0;
		} else if (2 == type) {
			if ("1".equals(it.getString("relatedInd")))
				add = add + 1.0;
		}
		return it;
	}

	private String relatedInd(String code) {
		for (Insurance i : insuranceList) {
			if (i.getCode().equals(code))
				return "1";
		}
		return "0";
	}

	private JSONObject getBus(String code, String type) {
		JSONObject it = new JSONObject();
		it.put("kindCode", code);// 险别代码
		it.put("insured", 0.0);// 保额--车上人员责任送入的为每人保额，其他险别送入的为总保额;除了车损险和盗抢险，其他险别该字段属于必传
		it.put("relatedInd", "0");// 是否投保不计免赔--1：是；0：否
		if (type.equals("1"))
			it.put("glassType", "2");// 玻璃险国别性质---投保玻璃险时，必须值：1.国产，2.进口
		else
			it.put("glassType", "1");
		return it;
	}

	private JSONObject getIns(Insurance i) {
		switch (i.getCode()) {
		case "BL":
			return getBus("01", 0.0, "BLD", 3);
		case "BT":
			return getBus("03", 0.0, "BTD", 3);
		case "BTR":
			return getBus("02", i.getAmount(), "BTRD", 3);
		case "BD":
			return getBus("041", i.getAmount(), "BDD", 1);
		case "BP":
			return getBus("044", i.getAmount(), "BPD", 1);
		case "BN":
			return getBus("21", i.getAmount(), "BND", 2);
		case "BG":
			return getBus("11", i.getType());
		case "BR":
			return null;
		case "BNP":
			return getBus("13", 0.0, "BNPD", 2);
		case "BW":
			return null;
		case "BWD":
			return null;
		default:
			return null;
		}
	}

}
